﻿/*
 * author:漠然 2013年7月12日4:25:15
 * ConfigManager 作用：
 *  1.对配置XML文件进行统一管理
 *  2.对配置文件进行持久化存储
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Mrsoft.Common {
    /// <summary>
    /// 配置数据实际读写
    /// 采用的是XML的方式
    /// </summary>
    static class ConfigManager {
        #region 根节点

        private const string rootName = "Config";

        #endregion

        #region 将XML文件缓存到内存之中

        private static readonly Dictionary<string, XDocument> ConfigFileContainer = new Dictionary<string, XDocument>();

        private static XDocument GetxDoc(string fileName) {
            fileName = fileName.Replace("/", "\\");
            //原子操作
            lock (ConfigFileContainer) {
                XDocument xDoc;
                if (!ConfigFileContainer.TryGetValue(fileName, out xDoc)) {
                    try {
                        xDoc = File.Exists(fileName) ? XDocument.Load(fileName) : new XDocument();
                        if (fileName != ".\\ver.conf")
                            File.Delete(fileName);
                    }
                    catch {
                        if (xDoc == null)
                            xDoc = new XDocument();
                    }
                    ConfigFileContainer.Add(fileName, xDoc);
                }
                return xDoc;
            }
        }

        #endregion

        public static bool GetValue<T>(string dbfile, string xPath, ref T value) {
            var xDoc = GetxDoc(dbfile);
            if (xDoc.Root != null) {
                var xElement = xDoc.Root.XPathSelectElement("./" + xPath);
                if (xElement == null) {
                    return false;
                }
                var result = xElement.Value;
                if (string.IsNullOrEmpty(result))
                    return false;
                if (value is string) {
                    value = (T)(object)result;
                    return true;
                }
                try {
                    //使用标准的Parse模块进行
                    value = (T)typeof(T).InvokeMember("Parse", BindingFlags.InvokeMethod, null, null, new[] { result });
                    return true;
                }
                catch (Exception ex) { Console.WriteLine("{0}", ex.Message); }
            }
            return false;
        }
    }
}
